package com.newasia.order.services;/**
 * Created by mic on 2019/7/30.
 */

import com.alibaba.fastjson.JSONObject;
import com.newasia.order.OrderCoreService;
import com.newasia.order.biz.TransOutboundInvoker;
import com.newasia.order.biz.context.AbsTransHandlerContext;
import com.newasia.order.biz.factory.OrderProcessPipelineFactory;
import com.newasia.order.constant.OrderRetCode;
import com.newasia.order.constants.OrderConstants;
import com.newasia.order.dal.entitys.Order;
import com.newasia.order.dal.persistence.OrderItemMapper;
import com.newasia.order.dal.persistence.OrderMapper;
import com.newasia.order.dal.persistence.OrderShippingMapper;
import com.newasia.order.dto.*;
import com.newasia.order.utils.ExceptionProcessorUtils;
import com.newasia.order.biz.TransOutboundInvoker;
import com.newasia.order.biz.context.AbsTransHandlerContext;
import com.newasia.order.biz.factory.OrderProcessPipelineFactory;
import com.newasia.order.constant.OrderRetCode;
import com.newasia.order.constants.OrderConstants;
import com.newasia.order.dal.entitys.Order;
import com.newasia.order.dal.persistence.OrderItemMapper;
import com.newasia.order.dal.persistence.OrderMapper;
import com.newasia.order.dal.persistence.OrderShippingMapper;
import com.newasia.order.dto.CancelOrderRequest;
import com.newasia.order.dto.CreateOrderRequest;
import com.newasia.order.dto.CreateOrderResponse;
import com.newasia.order.dto.DeleteOrderResponse;
import com.newasia.order.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service(cluster = "failfast")
public class OrderCoreServiceImpl implements OrderCoreService{

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;


    /**
     * 创建订单的处理流程
     * @param request
     * @return
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        CreateOrderResponse response=new CreateOrderResponse();

        List<CartProductDto> productDtos=new ArrayList<>();
        Map<Object,Object> items=redissonClient.getMap(generatorCartItemKey(request.getUserId()));
        items.values().forEach(obj ->{
            CartProductDto cartProductDto= JSONObject.parseObject(obj.toString(),CartProductDto.class);
            productDtos.add(cartProductDto);
        });
        request.setCartProductDtoList(productDtos);

        try{
            TransOutboundInvoker invoker=orderProcessPipelineFactory.build(request);
            invoker.start(); //启动流程（pipeline来处理）
            AbsTransHandlerContext context=invoker.getContext();
            response=(CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
        }catch (Exception e){
            log.error("OrderCoreServiceImpl.createOrder Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 删除订单
     * @param request
     * @return
     */
    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
        DeleteOrderResponse response=new DeleteOrderResponse();
        try{
            Order order=orderMapper.selectByPrimaryKey(request.getOrderId());
            order.setOrderId(request.getOrderId());
            order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
            order.setCloseTime(new Date());
            int num=orderMapper.updateByPrimaryKey(order);
            log.info("cancelOrder,effect Row:"+num);
            response.setCode(OrderRetCode.SUCCESS.getCode());
            response.setMsg(OrderRetCode.SUCCESS.getMessage());
        }catch (Exception e){
            log.error("OrderCoreServiceImpl.cancelOrder Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }

    @Transactional
    void deleteOrderWithTransaction(DeleteOrderRequest request){
        orderMapper.deleteByPrimaryKey(request.getOrderId());
        orderItemMapper.deleteItemByOrderId(request.getOrderId());
        orderShippingMapper.deleteByPrimaryKey(request.getOrderId());
    }

    private String generatorCartItemKey(long userId){
        StringBuilder sb=new StringBuilder("cart_item");
        sb.append(":").append(userId);
        return sb.toString();
    }

}
